﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using POSSystem.BLL;

namespace ShopOnline
{
    /// <summary>
    /// Summary description for FileUploadHandler
    /// </summary>
    public class FileUploadHandler : IHttpHandler
    {
        const int MAX_LOGO_WIDTH = 150;
        const int MAX_LOGO_HEIGHT = 110;

        public void ProcessRequest(HttpContext context)
        {
            if (string.IsNullOrEmpty(context.Request["type"]))
                HttpContext.Current.Response.Write(UploadImage(Guid.NewGuid().ToString(), Convert.ToInt32(context.Request["w"]), Convert.ToInt32(Convert.ToDouble(context.Request["h"]))));
            else
                HttpContext.Current.Response.Write(UploadLogo(Guid.NewGuid().ToString()));
        }

        private System.String UploadLogo(string id)
        {

            bool IsIE = false;
            string sFileName = "";
            var TempFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bcimages");

            DirectoryInfo dInfo = new DirectoryInfo(TempFolder);
            if (!dInfo.Exists)
                dInfo.Create();

            if ((HttpContext.Current.Request.Files == null) || (HttpContext.Current.Request.Files.Count == 0))
            {
                if (string.IsNullOrEmpty(HttpContext.Current.Request.Params["qqfile"]))
                {
                    return ("{success:false, error:'request file is empty 1'}");
                }
                else
                {
                    sFileName = HttpContext.Current.Request.Params["qqfile"].ToString();
                }
            }
            else
            {
                sFileName = HttpContext.Current.Request.Files[0].FileName;
                IsIE = true;
            }

            if (string.IsNullOrEmpty(sFileName))
            {
                return ("{success:false, error:'request file is empty 2'}");
            }

            string DocumentName = id + Path.GetExtension(sFileName);

            if (IsIE)
            {
                try
                {
                    Bitmap bitMap = new Bitmap(HttpContext.Current.Request.Files[0].InputStream);

                    int intWidth = bitMap.Width;
                    int intHeight = bitMap.Height;
                    if (intWidth > MAX_LOGO_WIDTH)
                    {
                        double dblCoef = intHeight / (double)intWidth;
                        intWidth = MAX_LOGO_WIDTH;
                        intHeight = Convert.ToInt32(dblCoef * MAX_LOGO_WIDTH);
                    }
                    if (intHeight > MAX_LOGO_HEIGHT)
                    {
                        double dblCoef = intWidth / (double)intHeight;
                        intHeight = MAX_LOGO_HEIGHT;
                        intWidth = Convert.ToInt32(dblCoef * MAX_LOGO_HEIGHT);
                    }

                    ResizeImageToStandard(HttpContext.Current.Request.Files[0], Path.Combine(TempFolder, DocumentName), intWidth, intHeight);
                }
                catch (Exception ex)
                {
                    ErrorLog.WriteToFile("upload", "", "error3:" + ex.Message);
                    return ("{success:false, error:'1" + ex.Message + "'}");
                }
            }
            else
            {
                try
                {
                    if ((HttpContext.Current.Request.InputStream != null) && (HttpContext.Current.Request.InputStream.CanRead) && (HttpContext.Current.Request.InputStream.Length > 0))
                    {
                        using (FileStream fileStream = new FileStream(Path.Combine(TempFolder, DocumentName), FileMode.Create))
                        {
                            //byte[] FileBytes = new byte[Convert.ToInt32(HttpContext.Current.Request.InputStream.Length) + 1];
                            Bitmap bitMap = new Bitmap(HttpContext.Current.Request.InputStream);
                            int intWidth = bitMap.Width;
                            int intHeight = bitMap.Height;
                            if (intWidth > MAX_LOGO_WIDTH)
                            {
                                double dblCoef = intHeight / (double)intWidth;
                                intWidth = MAX_LOGO_WIDTH;
                                intHeight = Convert.ToInt32(dblCoef * MAX_LOGO_WIDTH);
                            }
                            if (intHeight > MAX_LOGO_HEIGHT)
                            {
                                double dblCoef = intWidth / (double)intHeight;
                                intHeight = MAX_LOGO_HEIGHT;
                                intWidth = Convert.ToInt32(dblCoef * MAX_LOGO_HEIGHT);
                            }
                            byte[] FileBytes = this.ResizeFromStream(HttpContext.Current.Request.InputStream, DocumentName, intWidth, intHeight);
                            Int32 bytesRead = 0;
                            bytesRead = HttpContext.Current.Request.InputStream.Read(FileBytes, 0, FileBytes.Length);
                            fileStream.Write(FileBytes, 0, FileBytes.Length);
                            fileStream.Flush();
                            fileStream.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    return ("{success:false, error:'2" + ex.Message + "'}");
                }
            }

            var newFileName = DocumentName;
            return ("{success:true, newfilename: '" + newFileName + "'}");
        }

        private System.String UploadImage(string id, int width, int height)
        {
            bool IsIE = false;
            string sFileName = "";
            var TempFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bcimages");
            var OrgFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bcimages");

            DirectoryInfo dInfo = new DirectoryInfo(TempFolder);
            if (!dInfo.Exists)
                dInfo.Create();

            dInfo = new DirectoryInfo(OrgFolder);
            if (!dInfo.Exists) dInfo.Create();

            if ((HttpContext.Current.Request.Files == null) || (HttpContext.Current.Request.Files.Count == 0))
            {
                if (string.IsNullOrEmpty(HttpContext.Current.Request.Params["qqfile"]))
                {
                    return ("{success:false, error:'request file is empty'}");
                }
                else
                {
                    sFileName = HttpContext.Current.Request.Params["qqfile"].ToString();
                }
            }
            else
            {
                sFileName = HttpContext.Current.Request.Files[0].FileName;
                IsIE = true;
            }

            if (string.IsNullOrEmpty(sFileName))
            {
                return ("{success:false, error:'request file is empty'}");
            }

            string DocumentName = id + Path.GetExtension(sFileName);

            if (IsIE)
            {
                try
                {
                    //Save as thumb image
                    ResizeImageToStandard(HttpContext.Current.Request.Files[0], Path.Combine(TempFolder, DocumentName), width, height);
                    //Save as original image
                    //HttpContext.Current.Request.Files[0].SaveAs(Path.Combine(OrgFolder, DocumentName));
                }
                catch (Exception ex)
                {
                    return ("{success:false, error:'" + ex.Message + "'}");
                }
            }
            else
            {
                try
                {
                    if ((HttpContext.Current.Request.InputStream != null) && (HttpContext.Current.Request.InputStream.CanRead) && (HttpContext.Current.Request.InputStream.Length > 0))
                    {
                        Stream stream = HttpContext.Current.Request.InputStream;
                        using (FileStream fileStream = new FileStream(Path.Combine(OrgFolder, DocumentName), FileMode.Create))
                        {
                            byte[] FileBytes = new byte[stream.Length + 1];
                            Int32 bytesRead = 0;
                            bytesRead = stream.Read(FileBytes, 0, FileBytes.Length);
                            fileStream.Write(FileBytes, 0, FileBytes.Length);

                            fileStream.Close();
                        }
                        using (FileStream fileStream = new FileStream(Path.Combine(TempFolder, DocumentName), FileMode.Create))
                        {
                            byte[] FileBytes = this.ResizeFromStream(HttpContext.Current.Request.InputStream, DocumentName, width, height);
                            //Int32 bytesRead = 0;
                            //bytesRead = stream.Read(FileBytes, 0, FileBytes.Length);
                            fileStream.Write(FileBytes, 0, FileBytes.Length);

                            fileStream.Close();
                        }
                        
                    }
                }
                catch (Exception ex)
                {
                    return ("{success:false, error:'" + ex.Message + "'}");
                }
            }

            var newFileName = DocumentName;

            return ("{success:true, newfilename: '" + newFileName + "'}");

        }

        private void ResizeImageToStandard(HttpPostedFile file, string saveAs, int width, int height)
        {
            try
            {
                Bitmap originalBMP = new Bitmap(file.InputStream);
                Bitmap newBMP = new Bitmap(originalBMP, width, height);

                //Create a graphic based on the new bitmap
                Graphics oGraphics = Graphics.FromImage(newBMP);
                //Set the properties for the new graphic file
                oGraphics.SmoothingMode = SmoothingMode.HighQuality;
                oGraphics.InterpolationMode = InterpolationMode.High;

                //Draw the new graphic based on the resized bitmap
                oGraphics.DrawImage(originalBMP, 0, 0, width, height);

                newBMP.Save(saveAs);

                //Once finished with the bitmap objects, we deallocate them.
                originalBMP.Dispose();
                newBMP.Dispose();
                oGraphics.Dispose();
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        /// <summary>
        /// converts stream to bytearray for resized image
        /// </summary>
        /// <param name="MaxSideSize"></param>
        /// <param name="Buffer"></param>
        /// <returns></returns>
        public byte[] ResizeFromStream(Stream Buffer, string fileName, int width, int height)
        {
            byte[] byteArray = null;  // really make this an error gif

            try
            {

                Bitmap bitMap = new Bitmap(Buffer);
                int intOldWidth = bitMap.Width;
                int intOldHeight = bitMap.Height;

                int intNewWidth = width;
                int intNewHeight = height;

                Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
                System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
                System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);

                Graphics oGraphic = Graphics.FromImage(oThumbNail);
                oGraphic.CompositingQuality = CompositingQuality.HighQuality;
                oGraphic.SmoothingMode = SmoothingMode.HighQuality;
                oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle oRectangle = new Rectangle
                    (0, 0, ThumbNailSize.Width, ThumbNailSize.Height);

                oGraphic.DrawImage(oImg, oRectangle);

                MemoryStream ms = new MemoryStream();
                oThumbNail.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                oGraphic.Dispose();
                oImg.Dispose();
                ms.Close();
                ms.Dispose();
            }
            catch (Exception)
            {
                //int newSize = MaxSideSize - 20;
                Bitmap bitMap = new Bitmap(350, 200);
                Graphics g = Graphics.FromImage(bitMap);
                g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, 350, 200));

                Font font = new Font("Courier", 8);
                SolidBrush solidBrush = new SolidBrush(Color.Red);
                g.DrawString("Failed File", font, solidBrush, 10, 5);
                g.DrawString(fileName, font, solidBrush, 10, 50);

                MemoryStream ms = new MemoryStream();
                bitMap.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                ms.Close();
                ms.Dispose();
                bitMap.Dispose();
                solidBrush.Dispose();
                g.Dispose();
                font.Dispose();

            }
            return byteArray;
        }

        public bool ByteArrayToFile(string _FileName, byte[] _ByteArray)
        {

            try
            {
                // Open file for reading
                System.IO.FileStream _FileStream = new System.IO.FileStream(_FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write);

                // Writes a block of bytes to this stream using data from a byte array.
                _FileStream.Write(_ByteArray, 0, _ByteArray.Length);

                // close file stream
                _FileStream.Close();

                return true;
            }
            catch (Exception _Exception)
            {
                // Error
                throw new Exception("Exception caught in process: " + _Exception.ToString());
            }
            return false;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}